home *** CD-ROM | disk | FTP | other *** search
- program wator;
- {$C-}
- {***************************************************************************}
- {DECLARE GLOBAL VARIABLES USED BY ALL PROCEDURES}
- label start;
- var
- fish,sharks,fishmove,sharkmove,starve:array [0..1919]
- of integer;
- nfish,nsharks,fbreed,sbreed,slife:integer;
- i,j,k,l,m,n:integer;
- movup,movdn,movrt,movlt,nmoves,nmeals:integer;
- moveopts:array[1..4] of integer;
- currpos,newpos:integer;
- inchar:char;
- cycle,ncycles:integer;
- sumfish,sumsharks:integer;
- maxfish,minfish,maxsharks,minsharks:integer;
- sharkcycle,fishcycle:array[0..2000] of integer;
- screen1:array [0..1999] of integer absolute $b800:$0000;
- {*************************************************************************}
- procedure intro; {**AN INTRODUCTION TO THE PROGRAM**}
- begin
- writeln('This program simulates the planet WATOR as described in Scientific');
- writeln('American Computer Recreations column, December, 1984. WATOR is a');
- writeln('toroidal (donut-shaped) planet inhabited by fish and sharks. The');
- writeln('fish feed on a ubiquitous plankton and the sharks feed on the fish.');
- writeln('Time passes in discrete jumps or cycles. During each cycle, fish');
- writeln('move randomly to an unoccupied square, and reproduce if old enough.');
- writeln('Sharks move to a square occupied by a fish and eat it, if possible,');
- writeln('or move to an open square if no meals are available. Sharks will also');
- writeln('breed if old enough, but will starve if they do not eat within a specified');
- writeln('period of time. Parameters selected at the beginning of the run are as');
- writeln('follows:');
- writeln(' nfish: Number of fish at start of run-distributed randomly.');
- writeln(' nsharks: Number of sharks at start, also distributed randomly.');
- writeln(' fbreed: Number of cycles a fish must exist before reproducing.');
- writeln(' sbreed: Number of cycles sharks must exist before reproducing.');
- writeln(' starve: Number of cycles a shark has to find food before starving.');
- writeln(' ncycles: Number of cycles for this run (maximum of 2000).');
- writeln('On the screen, fish look like a dot (.) and sharks like a "O".');
- writeln('After the initial screen is displayed, press any key to start the');
- writeln('simulation. During the run, pressing any key will stop the program,');
- writeln('or the run will continue until ncycles is reached.');
- writeln('Press any key now to continue.');
- end;
- {*******************END PROCEDURE INTRO************************************}
- {**************************************************************************}
- procedure display;
- begin
- for i:=0 to 1919 do
- begin
- if fish[i]>-1 then screen1[i]:=3886
- else if sharks[i]>-1 then screen1[i]:=3919
- else screen1[i]:=3872;
- sharkmove[i]:=-1;
- end;
- end;
- {**********************END PROCEDURE DISPLAY*******************************}
- {**************************************************************************}
- procedure count;
- begin
- sumfish:=0;sumsharks:=0;
- for i:=0 to 1919 do
- begin
- if fish[i]>-1 then sumfish:=sumfish+1;
- if sharks[i]>-1 then sumsharks:=sumsharks+1;
- end;
- gotoxy(1,25);clreol;
- write('TOTAL FISH=',sumfish:4,'(MAX:',maxfish:4,',MIN:',minfish:4,') TOTAL');
- write(' SHARKS=',sumsharks:4,'(MAX:',maxsharks:4,',MIN:',minsharks:4,') ');
- write(cycle);
- end;
- {***************************************************************************}
- {PROCEDURE INITIALIZES ARRAYS, GETS STARTING PARAMETERS, SETS UP SCREEN*****}
- procedure initialize;
- begin
- cycle:=0;
- maxfish:=0;minfish:=0;maxsharks:=0;minsharks:=0;
- write ('nfish=? '); readln(nfish);
- write('nsharks=? ');readln(nsharks);
- write('fbreed=? ');readln(fbreed);
- write('sbreed=? ');readln(sbreed);
- write('slife=? ');readln(slife);
- write('how many cycles? ');readln(ncycles);
- for i:=0 to 1919 do
- begin
- fish[i]:=-1;sharks[i]:=-1;fishmove[i]:=-1;sharkmove[i]:=-1;
- starve[i]:=-1;
- end;
- for i:=1 to nfish do
- begin
- repeat
- j:=random(1920);
- until fish[j]=-1;
- fish[j]:=random(fbreed);
- end;
- for i:=1 to nsharks do
- begin
- repeat
- j:=random(1920);
- until (fish[j]=-1)and(sharks[j]=-1);
- sharks[j]:=random (sbreed);
- starve[j]:=random (slife);
- end;
- display;
- gotoxy(1,25);
- end;
- {*****************END PROCEDURE INITIALIZE**********************************}
- {}
- {*****************PROCEDURE MOVEFISH***************************************}
- procedure movefish;
- begin
- for j:=0 to 23 do begin
- k:=j*80;
- for i:=0 to 80 do begin
- {LOOK THROUGH ARRAY FOR FISH, CHECK IF ALREADY MOVED. IF NOT, THEN }
- currpos:=i+k;
- if (fish[currpos]>-1) and (fishmove[currpos]=-1) then begin
- if i=0 then movlt:=currpos+79 else movlt:=currpos-1;
- if i=79 then movrt:=currpos-79 else movrt:=currpos+1;
- if j=0 then movup:=currpos+1840 else movup:=currpos-80;
- if j=23 then movdn:=currpos-1840 else movdn:=currpos+80;
- nmoves:=0;
- {LOOK AROUND TO SEE WHERE FISH CAN BE MOVED}
- if (fish[movlt]=-1) and (sharks[movlt]=-1) then begin
- nmoves:=nmoves+1;
- moveopts[nmoves]:=1;
- end;
- if (fish[movrt]=-1) and (sharks[movrt]=-1) then begin
- nmoves:=nmoves+1;
- moveopts[nmoves]:=2;
- end;
- if (fish[movup]=-1) and (sharks[movup]=-1) then begin
- nmoves:=nmoves+1;
- moveopts[nmoves]:=3;
- end;
- if (fish[movdn]=-1) and (sharks[movdn]=-1) then begin
- nmoves:=nmoves+1;
- moveopts[nmoves]:=4;
- end;
- {IF NOWHERE TO GO THEY JUST GET OLDER}
- if nmoves=0 then begin if fish[currpos]=fbreed then fish[currpos]:=0
- else fish[currpos]:=fish[currpos]+1 end
- {OTHERWISE, PICK A MOVE TO MAKE}
- else begin
- l:=random (nmoves)+1;
- case moveopts[l] of
- 1:newpos:=movlt;
- 2:newpos:=movrt;
- 3:newpos:=movup;
- 4:newpos:=movdn;
- end; {END CASE STATEMENT}
- {THEN MAKE MOVE, FISH BREEDS IF OLD ENOUGH TO REPRODUCE}
- fishmove[newpos]:=1;
- if fish[currpos]=fbreed then begin
- fish[newpos]:=0;fish[currpos]:=0;end
- else begin fish[newpos]:=fish[currpos]+1;fish[currpos]:=-1;end;
- end;
- end;
- end;
- end;
- for i:=0 to 1999 do fishmove[i]:=-1;
- end;
- {}
- {******************END PROCEDURE MOVEFISH***********************************}
- {}
- procedure movesharks;
- begin
- for j:=0 to 23 do begin
- k:=j*80;
- for i:=0 to 79 do begin
- currpos:=i+k;
- {LOOK THROUGH ARRAY FOR sharks, CHECK IF ALREADY MOVED. IF NOT, THEN }
- if (sharks[currpos]>-1) and (sharkmove[currpos]=-1) then begin
- if i=0 then movlt:=currpos+79 else movlt:=currpos-1;
- if i=79 then movrt:=currpos-79 else movrt:=currpos+1;
- if j=0 then movup:=currpos+1840 else movup:=currpos-80;
- if j=23 then movdn:=currpos-1840 else movdn:=currpos+80;
- nmeals:=0;nmoves:=0;
- {LOOK AROUND TO SEE WHERE sharks CAN BE MOVED}
- if fish [movlt]>-1 then begin
- nmeals:=nmeals+1;
- moveopts[nmeals]:=1;
- end;
- if fish [movrt]>-1 then begin
- nmeals:=nmeals+1;
- moveopts[nmeals]:=2;
- end;
- if fish [movup]>-1 then begin
- nmeals:=nmeals+1;
- moveopts[nmeals]:=3;
- end;
- if fish [movdn]>-1 then begin
- nmeals:=nmeals+1;
- moveopts[nmeals]:=4;
- end;
- {IF THE SHARK FINDS A FISH TO EAT, THEN PICK ONE, EAT IT, BREED IF POSSIBLE}
- if nmeals>0 then begin
- l:=random(nmeals)+1;
- case moveopts[l] of
- 1:newpos:=movlt;
- 2:newpos:=movrt;
- 3:newpos:=movup;
- 4:newpos:=movdn;
- end;
- fish[newpos]:=-1;
- starve[newpos]:=0; sharkmove [newpos]:=1;
- if sharks[currpos]=sbreed then begin
- sharks[newpos]:=0;
- sharks[currpos]:=0; starve [currpos]:=0;
- end
- else begin
- sharks[newpos]:=sharks[currpos]+1;
- sharks[currpos]:=-1; starve [currpos]:=-1;
- end;
- end
- else if starve [currpos]<slife then begin
- {IF NO MEALS IN VICINITY, LOOK FOR AN EMPTY SQUARE TO MOVE TO}
- if (sharks[movlt]=-1) then begin
- nmoves:=nmoves+1;
- moveopts[nmoves]:=1;
- end;
- if (sharks[movrt]=-1) then begin
- nmoves:=nmoves+1;
- moveopts[nmoves]:=2;
- end;
- if (sharks[movup]=-1) then begin
- nmoves:=nmoves+1;
- moveopts[nmoves]:=3;
- end;
- if (sharks[movdn]=-1) then begin
- nmoves:=nmoves+1;
- moveopts[nmoves]:=4;
- end;
- {IF NOTHING TO EAT AND NO PLACE TO GO, SHARK GETS OLDER}
- if nmoves=0 then begin
- if sharks[currpos]=sbreed then sharks[currpos]:=0
- else sharks[currpos]:=sharks[currpos]+1;
- starve [currpos]:= starve [currpos]+1;
- end
- {}
- {IF THERE IS A MOVE TO MAKE, PICK ONE FROM AVAILABLE SQUARES}
- else begin
- l:=random (nmoves)+1;
- case moveopts[l] of
- 1:newpos:=movlt;
- 2:newpos:=movrt;
- 3:newpos:=movup;
- 4:newpos:=movdn;
- end;
- sharkmove[newpos]:=1;
- starve[newpos]:=starve[currpos]+1;
- if sharks[currpos]=sbreed then begin
- sharks[newpos]:=0;
- sharks[currpos]:=0; starve[currpos]:=0; end
- else begin
- sharks[newpos]:=sharks[currpos]+1;
- sharks[currpos]:=-1;starve[currpos]:=-1; end;
- end;
- end
- else begin
- sharks [currpos]:=-1; starve [currpos]:=-1;
- end;
- end;
- end;
- end;
- for i:=0 to 1999 do sharkmove[i]:=-1;
- end;
- {}
- {*********************END PROCEDURE MOVESHARKS******************************}
- {}
- {*********************BEGINNING OF MAIN PROGRAM*****************************}
- begin
- intro; repeat until keypressed; read (kbd,inchar);
- start:clrscr;initialize;count;
- maxfish:=sumfish;minfish:=sumfish;maxsharks:=sumsharks;minsharks:=sumsharks;
- fishcycle[0]:=sumfish;sharkcycle[0]:=sumsharks;
- repeat until keypressed;
- read (kbd,inchar);
- repeat
- movefish;
- movesharks;
- display;
- if sumfish>maxfish then maxfish:=sumfish
- else if sumfish<minfish then minfish:=sumfish;
- if sumsharks>maxsharks then maxsharks:=sumsharks
- else if sumsharks<minsharks then minsharks:=sumsharks;
- cycle:=cycle+1;
- count;fishcycle[cycle]:=sumfish;sharkcycle[cycle]:=sumsharks;
- until keypressed or (cycle=ncycles); read(kbd,inchar);
- clrscr;
- write('DO YOU WANT TO DO ANOTHER RUN? (Y/N): ');readln(inchar);
- if upcase(inchar)='Y' then goto start;
- end.